package fr.cephb.joperon.client;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;



import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.RequestBuilder;
import com.google.gwt.http.client.RequestCallback;
import com.google.gwt.http.client.RequestException;
import com.google.gwt.http.client.Response;
import com.google.gwt.http.client.URL;
import com.google.gwt.json.client.JSONArray;
import com.google.gwt.json.client.JSONBoolean;
import com.google.gwt.json.client.JSONNumber;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONParser;
import com.google.gwt.json.client.JSONValue;
import com.google.gwt.user.client.Cookies;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.ChangeListener;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.ComplexPanel;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.DecoratorPanel;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.DockPanel;
import com.google.gwt.user.client.ui.FileUpload;
import com.google.gwt.user.client.ui.FormPanel;
import com.google.gwt.user.client.ui.FormSubmitEvent;
import com.google.gwt.user.client.ui.Frame;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HasAlignment;
import com.google.gwt.user.client.ui.Hidden;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Hyperlink;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.NamedFrame;
import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.PasswordTextBox;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.StackPanel;
import com.google.gwt.user.client.ui.TabPanel;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.client.ui.HTMLTable.CellFormatter;



/**
 * Entry point classes define <code>onModuleLoad()</code>.
 */
public class OperonGWTClient implements EntryPoint
	{
	private static int KEY_GENERATOR=0;
	private static final String MIME_FORM_ENCODING= "application/x-www-form-urlencoded";
	public static final String HIDDEN_FRAME_NAME="hiddenFrame";
	//public static final String OPERON_BASE_URL="http://cabernet.cng.fr:8080/joperon"; 
	//public static final String OPERON_GWT_SERVLET=OPERON_BASE_URL+"/gwt";
	/** cookie value for session */
	private String jSessionId=null;
	/** user name */
	private String userLogin=null;
	/** user is admin ? */
	private boolean userIsAdmin=false;
	/** user is anonymous */
	private boolean userIsAnonymous=true;
	
	/** content Pane */
	private ScrollPanel mainPanel=null;
	/** hidden frame , hack to obtain a dialog saveTo...*/
	private NamedFrame hiddenFrame;
	/** check connexction */
	private PingRunner pingRunner=null;
	
	public static String getOperonBaseURL()
		{
		//GWTUtils.log(GWT.getModuleBaseURL());
		return GWT.getModuleBaseURL()+"../";
		}
	
	public String getGWTServlet()
		{
		//GWTUtils.log(getOperonBaseURL()+"gwt");
		return getOperonBaseURL()+"gwt";
		}
	
	private  class PingRunner extends Timer
		{
		@Override
		public void run()
			{
			
			if(userLogin==null || jSessionId==null)
				{
				return;
				}
			
			try {
				RequestBuilder builder = new RequestBuilder(RequestBuilder.POST,
						getGWTServlet()+"/ping");
				Cookies.setCookie("JSESSIONID",jSessionId);
				builder.setHeader("Content-Type",MIME_FORM_ENCODING);
				builder.sendRequest("login="+URL.encode(userLogin),new ObjectCallBack()
			  		{
					@Override
						public void onError(Request arg0, Throwable arg1) {
							handleBadAnswer();
							}
					
					@Override
					public void handleResponse(Request req, Response res) throws Exception
						{
						JSONObject o= parse(res);
						JSONBoolean ok = o.get("message").isBoolean();
						if(ok==null || !ok.booleanValue())
							{
							handleBadAnswer();
							}
						}
			  		});
				} 
			catch (Exception e) {
				GWTUtils.log(e);
				handleBadAnswer();
				}
			}
		
		
		
		private void handleBadAnswer()
			{
			GWTUtils.log("ping returned error");
			Window.alert("Sorry. The operon server was reloaded/updated.");
			doLogout();
			}
		
		
		}
	
	
	/** Shortcuts to create a Table */
	private class Table
		extends Composite
		{
		private int rows;
		private int cols;
		private Grid grid;
		private VerticalPanel vPanel;
		
		
		public Table(int rows,int cols)
			{
			this.rows=rows;
			this.cols=cols;
			this.grid= new Grid(rows+1,cols);
			this.grid.setWidth("100%");
			for(int i=0;i< cols;++i) setColumnName(i, String.valueOf(i+1));
			this.vPanel=new VerticalPanel();
			this.vPanel.add(this.grid);
			this.initWidget(vPanel);
			}
		
		public void setColumnName(int col,String content)
			{
			Label label=new Label(content);
			label.setStyleName("label4tableheader");
			setColumnName(col,label);
			}
		
		public void setColumnName(int col,Widget content)
			{
			grid.setWidget(0, col, content);
			CellFormatter fmt= this.grid.getCellFormatter();
			fmt.setHorizontalAlignment(0, col,HasAlignment.ALIGN_CENTER);
			}
		
		public void setColumnNames(String... content)
			{
			for(int i=0;i< content.length && i< this.cols;++i)
				{
				setColumnName(i, content[i]);
				}
			}
		
		public void setValueAt(int row,int col,String content)
			{
			this.setValueAt(row, col, new Label(content));
			}
		
		public void setValueAt(int row,int col,JSONObject object,String member)
			{
			if(object==null || member==null || !object.containsKey(member)) return;
			JSONValue v= object.get(member);
			if(v==null)
				{
				setValueAt(row, col, "N/A");
				}
			else if(v.isString()!=null)
				{
				setValueAt(row, col, v.isString().stringValue());
				}
			else
				{
				setValueAt(row, col, v.toString());
				}
			}
		
		public void setValueAt(int row,int col,Widget content)
			{
			if(row <0 || row>=this.rows || col<0 || col>=this.cols) return;
			this.grid.setWidget(row+1, col, content);
			}
		
		public void setRowAt(int row,String...values)
			{
			Widget w[]= new Widget[Math.min(values.length, this.cols)];
			for(int i=0;i< w.length;++i)
				{
				w[i]=new Label(values[i]);
				}
			setRowAt(row,w);
			}
		
		public void setRowAt(int row,Widget...values)
			{
			for(int i=0;i< values.length && i< this.cols;++i)
				{
				setValueAt(row, i, values[i]);
				}
			}
		VerticalPanel getContentPane()
			{
			return this.vPanel;
			}
		}
	
	/** callback throwing error on failure and cachting any error on success */
	private abstract class ObjectCallBack
		extends CallbackAdapter
		{
		public ObjectCallBack(Object...objs )
			{
			super(objs);
			}
		
		public void handleResponse(Request request, Response response) throws Exception
			{
			throw new Exception("Not implemented");
			}
		
		@Override
		public void onResponseReceived(Request request, Response response)
			{
			try {
				handleResponse(request,response);
			} catch (Exception error)
				{
				GWTUtils.log(error);
				GWTUtils.log("response was "+response.getText());
				alert(error.getMessage());
				}
			}
		
		@Override
		public void onError(Request request, Throwable error)
			{
			GWTUtils.log(error);
			alert(error.getMessage());
			}
		}
	
	
	/**
	 * Stupid listener called for a project
	 * @author lindenb
	 *
	 */
	class ProjectClicked extends ClickAdapter
		{
		ProjectClicked(String pid)
			{
			super(pid);
			}
		@Override
		public void onClick(Widget sender)
			{
			doShowProject((String)getObject(0));
			}
		}
	
	/**
	 * SnpMapPane
	 */
	private class SnpMapPane
		{
		private FormPanel contentPane;
		private ListBox assemblyList;
		private VerticalPanel mPanelsPane = null;
		
		SnpMapPane()
			{
			this.contentPane = new FormPanel("frame"+(HIDDEN_FRAME_NAME));
			
			this.contentPane.setMethod(FormPanel.METHOD_POST);
			this.contentPane.setEncoding(FormPanel.ENCODING_MULTIPART);
			this.contentPane.setAction(getOperonBaseURL()+"/operon");
			this.contentPane.setWidth("100%");
			DockPanel mainPane = new DockPanel();
			mainPane.setWidth("100%");
			TabPanel tabPanel= new TabPanel();
			mainPane.add(tabPanel,DockPanel.CENTER);
			this.contentPane.setWidget(mainPane);
			
			
			VerticalPanel pane= new VerticalPanel();
			tabPanel.add(pane, "Search Form");
			
			HorizontalPanel h1= new HorizontalPanel();
			pane.add(h1);
			
			
			Hidden hidden= new Hidden("step","4");
			h1.add(hidden);
			hidden= new Hidden("act","altera");
			h1.add(hidden);
			
			Label label= new Label("Assembly:");
			label.setStyleName("label4form");
			h1.add(label);
			assemblyList= new ListBox(false);
			assemblyList.setName("as");
			h1.add(assemblyList);
			
			
			h1= new HorizontalPanel();
			pane.add(h1);
			label= new Label(" Chromosome:");
			label.setStyleName("label4form");
			h1.add(label);
			TextBox tbox= new TextBox();
			tbox.setName("chrom");
			h1.add(tbox);
			
			h1= new HorizontalPanel();
			pane.add(h1);
			label= new Label(" From:");
			label.setStyleName("label4form");
			h1.add(label);
			tbox= new TextBox();
			tbox.setName("start");
			h1.add(tbox);
			
			h1= new HorizontalPanel();
			pane.add(h1);
			label= new Label(" To:");
			label.setStyleName("label4form");
			h1.add(label);
			tbox= new TextBox();
			tbox.setName("end");
			h1.add(tbox);
			
			
			pane= new VerticalPanel();
			tabPanel.add(pane, "Optional Parameters");
			
			/*h1= new HorizontalPanel();
			pane.add(h1);
			label= new Label("Filter Flags:");
			label.setStyleName("label4form");
			h1.add(label);
			tbox= new TextBox();
			tbox.setName("filterflags");
			h1.add(tbox);*/
			
			/*h1= new HorizontalPanel();
			pane.add(h1);
			label= new Label("Minimum SNP confidence value:");
			label.setStyleName("label4form");
			h1.add(label);
			tbox= new TextBox();
			tbox.setName("minsnpconfidence");
			h1.add(tbox);*/
			
			/*h1= new HorizontalPanel();
			pane.add(h1);
			label= new Label(" Variation type and genotype restriction:");
			label.setStyleName("label4form");
			h1.add(label);
			ListBox actionBox= new ListBox(false);
			actionBox.setName("oid");
			actionBox.addItem("Show only SNPs with genotype results in selected panels", "87");
			actionBox.addItem("Do not restric output", "0");
			actionBox.addItem("Show only single nucleotide polymorphisms", "21");
			actionBox.addItem("Show only deletions", "23");
			actionBox.addItem("Show only insertions", "22");
			actionBox.addItem("Show only complex SNP polymorphisms", "24");
			actionBox.addItem("Show other sequence variants", "25");
			h1.add(actionBox);*/
			
			
			h1= new HorizontalPanel();
			pane.add(h1);
			label= new Label("Output");
			label.setStyleName("label4form");
			h1.add(label);
			ListBox actionBox= new ListBox(false);
			actionBox.setName("fmt");
			actionBox.addItem("HTML", "html");
			actionBox.addItem("Text", "text");
			h1.add(actionBox);
			
			
			mPanelsPane= new VerticalPanel();
			tabPanel.add(mPanelsPane, "Markers Panel");
			
			h1= new HorizontalPanel();
			mainPane.add(h1,DockPanel.SOUTH);
			h1.add(new SubmitButton());
			
			reloadAssemblies();
			reloadMPanels();
			tabPanel.selectTab(0);
			}
		
		
		
		private void reloadAssemblies()
			{
			try {
				RequestBuilder builder = new RequestBuilder(RequestBuilder.POST,
						getGWTServlet()+"/assemblies");
				Cookies.setCookie("JSESSIONID",jSessionId);
				builder.setHeader("Content-Type",MIME_FORM_ENCODING);
				builder.sendRequest(null,new ObjectCallBack(assemblyList)
			  		{
					@Override
					public void handleResponse(Request req, Response res) throws Exception
						{
						while(assemblyList.getItemCount()!=0)
							{
							assemblyList.removeItem(0);
							}
						JSONObject o= parse(res);
						JSONArray array = o.get("message").isArray();
						
						for(int i=0;i<array.size();++i)
							{
							JSONObject org= array.get(i).isObject();
							assemblyList.addItem( toStr(org, "name"),toStr(org, "id"));
							}
						}
			  		});
				} 
			catch (Exception e) {
				alert(e.getMessage());
				}
			}
		
		private void reloadMPanels()
			{
			try {
				RequestBuilder builder = new RequestBuilder(
						RequestBuilder.POST,
						getGWTServlet()+"/mpanels");
				Cookies.setCookie("JSESSIONID",jSessionId);
				builder.setHeader("Content-Type",MIME_FORM_ENCODING);
				builder.sendRequest(null,new ObjectCallBack(mPanelsPane)
			  		{
					@Override
					public void handleResponse(Request req, Response res) throws Exception
						{
						removeAll(mPanelsPane);
						
						JSONObject o= parse(res);
						JSONArray array = path(o,"message.mpanels").isArray();
	
						for(int i=0;i<array.size();++i)
							{
							JSONObject mpanel = array.get(i).isObject();
							CheckBox cb= new CheckBox(toStr(mpanel, "syn"));
							cb.setName("mpanel");
							GWTUtils.setValue(cb, toStr(mpanel, "uid"));
							mPanelsPane.add(cb);
							}
						}
			  		});
				} 
			catch (Exception e) {
				GWT.log("error", e);
				alert(e.getMessage());
				}
			}
		
		}
	
	
	/**
	 * SpindlePane
	 */
	private class SpindlePane
		{
		private FormPanel contentPane;
		private ListBox assemblyList;
		private ListBox prjdna;
		
		SpindlePane()
			{
			this.contentPane = new FormPanel(OperonGWTClient.HIDDEN_FRAME_NAME);
			
			this.contentPane.setMethod(FormPanel.METHOD_GET);
			this.contentPane.setEncoding(FormPanel.ENCODING_MULTIPART);
			this.contentPane.setAction(getOperonBaseURL()+"/operon");
			this.contentPane.setWidth("100%");
			DockPanel mainPane = new DockPanel();
			mainPane.setWidth("100%");
			TabPanel tabPanel= new TabPanel();
			mainPane.add(tabPanel,DockPanel.CENTER);
			this.contentPane.setWidget(mainPane);
			
			
			VerticalPanel pane= new VerticalPanel();
			tabPanel.add(pane, "Search Form");
			
			HorizontalPanel h1= new HorizontalPanel();
			pane.add(h1);
			
			
			Hidden hidden= new Hidden("step","1");
			h1.add(hidden);
			hidden= new Hidden("act","spindle-allele");
			h1.add(hidden);
			
			Label label= new Label("Assembly:");
			label.setStyleName("label4form");
			h1.add(label);
			assemblyList= new ListBox(false);
			assemblyList.setName("as");
			h1.add(assemblyList);
			
			
			h1= new HorizontalPanel();
			pane.add(h1);
			label= new Label(" Chromosome:");
			label.setStyleName("label4form");
			h1.add(label);
			TextBox tbox= new TextBox();
			tbox.setName("chrom");
			h1.add(tbox);
			
			h1= new HorizontalPanel();
			pane.add(h1);
			label= new Label(" From:");
			label.setStyleName("label4form");
			h1.add(label);
			tbox= new TextBox();
			tbox.setName("start");
			h1.add(tbox);
			
			h1= new HorizontalPanel();
			pane.add(h1);
			label= new Label(" To:");
			label.setStyleName("label4form");
			h1.add(label);
			tbox= new TextBox();
			tbox.setName("end");
			h1.add(tbox);
			
			h1= new HorizontalPanel();
			pane.add(h1);
			label= new Label(" DNA Panel:");
			label.setStyleName("label4form");
			h1.add(label);
			this.prjdna= new ListBox();
			this.prjdna.setName("prjfin4dna");
			h1.add(this.prjdna);
			

			
			h1= new HorizontalPanel();
			pane.add(h1);
			label= new Label("Format:");
			label.setStyleName("label4form");
			h1.add(label);
			ListBox actionBox= new ListBox(false);
			actionBox.setName("format");
			actionBox.addItem("DNA sample and genotype by row", "row");
			actionBox.addItem("DNA sample and genotype by column", "column");
			h1.add(actionBox);
			
			
			h1= new HorizontalPanel();
			mainPane.add(h1,DockPanel.SOUTH);
			h1.add(new SubmitButton());
			
			this.assemblyList.addChangeListener(new ChangeListener()
				{
				public void onChange(Widget sender) {
					reloadPrjDna();
					}
				});
			
			reloadAssemblies();
			// done reloadPrjDna();
			tabPanel.selectTab(0);
			}
		
		
		
		private void reloadAssemblies()
			{
			try {
				RequestBuilder builder = new RequestBuilder(RequestBuilder.POST,
						getGWTServlet()+"/assemblies");
				Cookies.setCookie("JSESSIONID",jSessionId);
				builder.setHeader("Content-Type",MIME_FORM_ENCODING);
				builder.sendRequest(null,new ObjectCallBack(assemblyList)
			  		{
					@Override
					public void handleResponse(Request req, Response res) throws Exception
						{
						while(assemblyList.getItemCount()!=0)
							{
							assemblyList.removeItem(0);
							}
						JSONObject o= parse(res);
						JSONArray array = o.get("message").isArray();
						
						for(int i=0;i<array.size();++i)
							{
							JSONObject org= array.get(i).isObject();
							assemblyList.addItem( toStr(org, "name"),toStr(org, "id"));
							}
						assemblyList.setSelectedIndex(0);
						reloadPrjDna();
						}
			  		});
				} 
			catch (Exception e) {
				alert(e.getMessage());
				}
			}
		
		private void reloadPrjDna()
			{
			try {
				RequestBuilder builder = new RequestBuilder(
						RequestBuilder.POST,
						getGWTServlet()+"/prjfins"
						);
				builder.setHeader("Content-Type",MIME_FORM_ENCODING);
				Cookies.setCookie("JSESSIONID",jSessionId);
				while(this.prjdna.getItemCount()!=0)
					{
					this.prjdna.removeItem(0);
					}
				int selIndex= assemblyList.getSelectedIndex();
				if(selIndex==-1) return;
				StringBuffer sb= new StringBuffer("target=DNA");
				sb.append("&as=").append(URL.encode(assemblyList.getValue(selIndex)));
				//GWTUtils.log(sb.toString());
				
				builder.sendRequest(sb.toString(),new ObjectCallBack()
			  		{
					@Override
					public void handleResponse(Request req, Response res) throws Exception
						{
						JSONObject o= parse(res);
						JSONArray array = path(o,"message.prjfin").isArray();
						
						for(int i=0;i<array.size();++i)
							{
							JSONObject mpanel = array.get(i).isObject();
							prjdna.addItem(toStr(mpanel, "def"), toStr(mpanel, "projCode"));
							}
						if(array.size()==0)
							{
							//Frame f= new Frame("help/export09.html");
							//f.setStyleName("helpframe");
							//genotypesPane.add(f);
							}
						}
			  		});
				} 
			catch (Exception e) {
				GWT.log("error", e);
				alert(e.getMessage());
				}
			}
		
		}
	
	
	
	
	/**
	 * Panel for exporting
	 *
	 */
	private class ExportPane
		{
		private FormPanel contentPane;
		private VerticalPanel organismsPane=null;
		private VerticalPanel mPanelsPane=null;
		private VerticalPanel genotypesPane=null;
		private ListBox userListOfSNP=null;
		private List<CheckBox> cBoxAssemblies= new ArrayList<CheckBox>();
		
		ExportPane()
			{
			this.contentPane = new FormPanel(hiddenFrame);
			this.contentPane.setMethod(FormPanel.METHOD_POST);
			this.contentPane.setEncoding(FormPanel.ENCODING_MULTIPART);
			this.contentPane.setAction(getGWTServlet()+"/aboutsnp");
			this.contentPane.setWidth("100%");
			
			DockPanel mainPane = new DockPanel();
			mainPane.setWidth("100%");
			mainPane.add(new Label("Export"),DockPanel.NORTH);
			
			TabPanel tabPanel= new TabPanel();
			mainPane.add(tabPanel,DockPanel.CENTER);
			
			
			
			this.contentPane.setWidget(mainPane);
			
			/** help */
			Frame frame01= new Frame("help/export.html");
			frame01.setStyleName("helpframe");
			tabPanel.add(frame01, "Export");
			
			/* Organisms */
			this.organismsPane = new VerticalPanel();
			DockPanel dock01= new DockPanel();
			dock01.setWidth("100%");
			dock01.add(this.organismsPane,DockPanel.CENTER);
			frame01= new Frame("help/export04.html");
			frame01.setStyleName("helpframe");
			dock01.add(frame01,DockPanel.EAST);
			tabPanel.add(dock01, "Organisms");
			
			/* population hapmap (mpanels ) */
			this.mPanelsPane=new VerticalPanel();
			dock01= new DockPanel();
			dock01.setWidth("100%");
			dock01.add(this.mPanelsPane,DockPanel.CENTER);
			frame01= new Frame("help/export05.html");
			frame01.setStyleName("helpframe");
			dock01.add(frame01,DockPanel.EAST);
			tabPanel.add(dock01,"Frequencies");
			
			/* genotypes */
			 dock01= new DockPanel();
			dock01.setWidth("100%");
			this.genotypesPane=new VerticalPanel();
			this.genotypesPane.setWidth("100%");
			frame01= new Frame("help/export06.html");
			frame01.setStyleName("helpframe");
			dock01.add(this.genotypesPane,DockPanel.CENTER);
			tabPanel.add(dock01,"Genotypes");
			
			
			/* type of input */
			VerticalPanel techPane= new VerticalPanel();
			
			dock01= new DockPanel();
			dock01.setWidth("100%");
			dock01.add(new Label("Select the technology."),DockPanel.NORTH);
			dock01.add(techPane,DockPanel.CENTER);
			frame01= new Frame("help/export07.html");
			frame01.setStyleName("helpframe");
			frame01.setWidth("100%");
			frame01.setHeight("150px");
			dock01.add(frame01,DockPanel.EAST);
			tabPanel.add(dock01, "Assay Type");
			for(String s:new String[]{"Taqman","Snplex","Fasta","Illumina","Sequenom"})
				{
				CheckBox cb= new CheckBox(s);
				cb.setName("fmt");
				GWTUtils.setValue(cb, s.toLowerCase());
				techPane.add(cb);
				}
			
			
			/* input */
			TabPanel tabInput= new TabPanel();
			tabPanel.add(tabInput, "Input");
			
			// input is textarea
			TextArea areaInput= new TextArea();
			areaInput.setWidth("100%");
			areaInput.setHeight("100px");
			areaInput.setName("area");
			dock01= new DockPanel();
			dock01.setWidth("100%");
			dock01.add(new Label("Copy and Paste your List of SNP Below."),DockPanel.NORTH);
			dock01.add(areaInput,DockPanel.CENTER);
			frame01= new Frame("help/export02.html");
			frame01.setStyleName("helpframe");
			frame01.setWidth("100%");
			frame01.setHeight("150px");
			dock01.add(frame01,DockPanel.SOUTH);
			tabInput.add(dock01, "Text Area");
			
			//input is upload file
			DockPanel pane2= new DockPanel();
			pane2.add(new Label("Upload a file of SNP."),DockPanel.NORTH);
			FileUpload fileInput= new FileUpload();
			fileInput.setName("file");
			pane2.add(fileInput,DockPanel.CENTER);
			frame01= new Frame("help/export03.html");
			frame01.setStyleName("helpframe");
			pane2.add(frame01,DockPanel.SOUTH);
			
			tabInput.add(pane2, "File Input");
			
			//input is proj snp
			this.userListOfSNP = new ListBox();
			pane2= new DockPanel();
			pane2.add(new Label("Select a list of SNP"),DockPanel.NORTH);
			this.userListOfSNP.setName("prjfin");
			this.userListOfSNP.setMultipleSelect(false);
			pane2.add(this.userListOfSNP ,DockPanel.CENTER);
			frame01= new Frame("help/export08.html");
			frame01.setStyleName("helpframe");
			pane2.add(frame01,DockPanel.NORTH);
			tabInput.add(pane2, "PrjSNP");
			tabInput.selectTab(0);
			
			/* submit button */
			HorizontalPanel h2= new HorizontalPanel();
			mainPane.add(h2,DockPanel.SOUTH);
			h2.add(new SubmitButton());
			
			reloadAssemblies();
			reloadMPanels();
			realoadUserListOfDNA();
			realoadUserListOfSNP();
			tabPanel.selectTab(0);
			}
		
		private void reloadAssemblies()
			{
			try {
				RequestBuilder builder = new RequestBuilder(RequestBuilder.POST,
						getGWTServlet()+"/assemblies");
				Cookies.setCookie("JSESSIONID",jSessionId);
				builder.setHeader("Content-Type",MIME_FORM_ENCODING);
				builder.sendRequest(null,new ObjectCallBack(organismsPane)
			  		{
					@Override
					public void handleResponse(Request req, Response res) throws Exception
						{
						removeAll(organismsPane);
						cBoxAssemblies.clear();
						JSONObject o= parse(res);
						JSONArray array = o.get("message").isArray();
						
						for(int i=0;i<array.size();++i)
							{
							JSONObject org= array.get(i).isObject();
							CheckBox cb= new CheckBox(toStr(org, "name"));
							cb.setName("as");
							GWTUtils.setValue(cb, toStr(org, "id"));
							cBoxAssemblies.add(cb);
							cb.addClickListener(new ClickListener()
								{
								public void onClick(Widget w)
									{
									
									realoadUserListOfDNA();
									realoadUserListOfSNP();
									}
								});
							organismsPane.add(cb);
							}
						}
			  		});
				} 
			catch (Exception e) {
				alert(e.getMessage());
				}
			}
	
		
		private void reloadMPanels()
			{
			try {
				RequestBuilder builder = new RequestBuilder(
						RequestBuilder.POST,
						getGWTServlet()+"/mpanels");
				Cookies.setCookie("JSESSIONID",jSessionId);
				builder.setHeader("Content-Type",MIME_FORM_ENCODING);
				builder.sendRequest(null,new ObjectCallBack(mPanelsPane)
			  		{
					@Override
					public void handleResponse(Request req, Response res) throws Exception
						{
						removeAll(mPanelsPane);
						
						JSONObject o= parse(res);
						JSONArray array = path(o,"message.mpanels").isArray();

						for(int i=0;i<array.size();++i)
							{
							JSONObject mpanel = array.get(i).isObject();
							CheckBox cb= new CheckBox(toStr(mpanel, "syn"));
							cb.setName("mpanel");
							GWTUtils.setValue(cb, toStr(mpanel, "acn"));
							mPanelsPane.add(cb);
							}
						}
			  		});
				} 
			catch (Exception e) {
				GWT.log("error", e);
				alert(e.getMessage());
				}
			}
		
		private void realoadUserListOfDNA()
			{
			try {
				RequestBuilder builder = new RequestBuilder(
						RequestBuilder.POST,
						getGWTServlet()+"/prjfins"
						);
				builder.setHeader("Content-Type",MIME_FORM_ENCODING);
				Cookies.setCookie("JSESSIONID",jSessionId);
				if(cBoxAssemblies.isEmpty())
					{
					removeAll(genotypesPane);
					return;
					}
				StringBuffer sb= new StringBuffer("target=DNA");
				for(int i=0;i< cBoxAssemblies.size();++i)
					{
					sb.append("&as=").append(URL.encode(GWTUtils.getValue(cBoxAssemblies.get(i))));
					}
				builder.sendRequest(sb.toString(),new ObjectCallBack(genotypesPane)
			  		{
					@Override
					public void handleResponse(Request req, Response res) throws Exception
						{
						
						removeAll(genotypesPane);
						JSONObject o= parse(res);
						JSONArray array = path(o,"message.prjfin").isArray();
						
						for(int i=0;i<array.size();++i)
							{
							JSONObject mpanel = array.get(i).isObject();
							CheckBox cb= new CheckBox(toStr(mpanel, "def"));
							cb.setName("prjfin4dna");
							GWTUtils.setValue(cb, toStr(mpanel, "projCode"));
							genotypesPane.add(cb);
							}
						if(array.size()==0)
							{
							Frame f= new Frame("help/export09.html");
							f.setStyleName("helpframe");
							genotypesPane.add(f);
							}
						}
			  		});
				} 
			catch (Exception e) {
				GWT.log("error", e);
				alert(e.getMessage());
				}
			}
		
		private void realoadUserListOfSNP()
			{
			try {
				RequestBuilder builder = new RequestBuilder(
						RequestBuilder.POST,
						getGWTServlet()+"/prjfins"
						);
				builder.setHeader("Content-Type",MIME_FORM_ENCODING);
				Cookies.setCookie("JSESSIONID",jSessionId);
				
				while(userListOfSNP.getItemCount()>0) userListOfSNP.removeItem(0);
				
				StringBuffer sb= new StringBuffer("target=SNP");
				for(int i=0;i< cBoxAssemblies.size();++i)
					{
					sb.append("&as=").append(URL.encode(GWTUtils.getValue(cBoxAssemblies.get(i))));
					}
				builder.sendRequest(sb.toString(),new ObjectCallBack(userListOfSNP)
			  		{
					@Override
					public void handleResponse(Request req, Response res) throws Exception
						{
						
							JSONObject o= parse(res);
							JSONArray array = path(o,"message.prjfin").isArray();
							
							for(int i=0;i<array.size();++i)
								{
								JSONObject mpanel = array.get(i).isObject();
								userListOfSNP.addItem(
									toStr(mpanel, "def"), 
									toStr(mpanel, "projCode")
									);
								}
							
						}
			  		});
				} 
			catch (Exception e) {
				GWT.log("error", e);
				alert(e.getMessage());
				}
			}
		}
	
	
	
  /**
   * This is the entry point method.
   */
  public void onModuleLoad()
  	{
	buildWelcomeScreen();
  	}
  
  

  /** build welcome screen */
 private void buildWelcomeScreen()
 	{
	this.jSessionId=null;
	this.userIsAdmin=false;
	this.userIsAnonymous=true;
	
	this.mainPanel=null;
	Cookies.removeCookie("JSESSIONID");
	RootPanel root= RootPanel.get();
	root.setWidth("100%");
	removeAll(root);
	
	 Image img = new Image("operon-logo.png");
	    Button button = new Button("Click me");
	    
	    // We can add style names
	    button.addStyleName("pc-template-btn");
	    // or we can set an id on a specific element for styling
	    img.getElement().setId("pc-template-img");
	    
	    VerticalPanel vPanel = new VerticalPanel();
	    vPanel.setWidth("100%");
	    vPanel.setHorizontalAlignment(VerticalPanel.ALIGN_CENTER);
	    vPanel.add(img);
	    
	    TextBox textBoxLogin= new TextBox();
	    textBoxLogin.setText(this.userLogin==null?"anonymous":this.userLogin);
	    PasswordTextBox textBoxPassword = new PasswordTextBox();
	    Grid grid= new Grid(3,2);
	    grid.setWidget(0, 0, new Label("Login"));
	    grid.setWidget(0, 1, textBoxLogin);
	    
	    grid.setWidget(1, 0, new Label("Password"));
	    grid.setWidget(1, 1, textBoxPassword);
	    grid.setWidget(2, 1, new Button("Login", new ClickAdapter(textBoxLogin,textBoxPassword)
	    	{
	    	public void onClick(Widget sender) {
	    		doLogin((TextBox)getObject(0),
	    				(PasswordTextBox)getObject(1)
	    				);
	    		}
	    	}));
	    
	   vPanel.add(grid);
	   
	   root.add(vPanel);
 	   }
  
 private static void removeAll(ComplexPanel root)
 	{
	 while( root.getWidgetCount()!=0)
		{
		root.remove(0);
		}
 	}
 
 private static void removeAll(ScrollPanel root)
	{
	Widget w= root.getWidget();
	if(w!=null) root.remove(w);
	}
 
 /** build main  screen */
 private void buildGUI()
 	{
	RootPanel root= RootPanel.get();
	root.setWidth("100%");
	removeAll(root);
	DockPanel dock01= new DockPanel();
	dock01.setSpacing(4);
	dock01.setWidth("150px");
	dock01.setHorizontalAlignment(DockPanel.ALIGN_CENTER);

	HorizontalPanel top= new HorizontalPanel();
	top.add(new Image("operon-logo.png"));
	dock01.add(top, DockPanel.NORTH);
	top.setWidth("100%");
	top.setHeight("159px");
	
	StackPanel leftMenu= new StackPanel();
	dock01.add(leftMenu, DockPanel.WEST);
	
	//control login/pane
	VerticalPanel pane01= new VerticalPanel();
	leftMenu.add(pane01, "Dashboard");
	pane01.add(new Label("Connected as "+this.userLogin));
	pane01.add(new Button("Help",new ClickListener()
		{
		public void onClick(Widget sender) {
			doShowMainHelp();
			}
		}));
	
	pane01.add(new Button("Logout",new ClickListener()
		{
		public void onClick(Widget sender) {
			doLogout();
			}
		}));
	
	//Projects Pane
	pane01= new VerticalPanel();
	leftMenu.add(pane01, "Projects");
	pane01.add(new Button("List Projects",new ClickListener()
		{
		public void onClick(Widget sender) {
			showProjects();
			}
		}));
	
	
	Button button=null;
	pane01.add(button=new Button("Add Project",new ClickAdapter()
		{
		@Override
		public void onClick(Widget w) {
			doShowCreateProject();
			}
		}));
	button.setEnabled(!this.userIsAnonymous);
	
	pane01= new VerticalPanel();
	leftMenu.add(pane01, "Tools");
	pane01.add(new Button("SNP Tool",new ClickAdapter()
		{
		@Override
		public void onClick(Widget arg0) {
			doShowExport();
			}
		}));
	
	pane01.add(new Button("SNP Map",new ClickAdapter()
		{
		@Override
		public void onClick(Widget arg0) {
			doShowSNPMap();
			}
		}));
	
	
	pane01.add(new Button("Genotypes",new ClickAdapter()
		{
		@Override
		public void onClick(Widget arg0) {
			doShowSpindleAlleles();
			}
		}));
	
	if(userIsAdmin)
		{
		pane01= new VerticalPanel();
		leftMenu.add(pane01, "Admin");
		pane01.add(new Button("Create User",new ClickListener()
			{
			public void onClick(Widget arg0) {
				doShowCreateUser();
				}
			}));
		}
	
	ScrollPanel scroller=new ScrollPanel(new Label());
	this.mainPanel=scroller;
	
	scroller.setSize(+(Window.getClientWidth()-160)+"px", ""+(Window.getClientHeight()-30)+"px");
	dock01.add(scroller,DockPanel.CENTER);
	
	
	HorizontalPanel bot= new HorizontalPanel();
	bot.add(new Label("Operon Mario Folgio CNG, Pierre Lindenbaum CEPH."));
	dock01.add(bot, DockPanel.SOUTH);
	
	
	this.hiddenFrame = new NamedFrame(HIDDEN_FRAME_NAME);
	this.hiddenFrame.setVisible(false);
	bot.add(this.hiddenFrame);
	root.add(dock01);
 	}
  
  public void doTest()
	{
	 if(this.jSessionId==null) return;
	RequestBuilder builder = new RequestBuilder(
			RequestBuilder.POST,
			getGWTServlet()+"/test"
			);
	Cookies.setCookie("JSESSIONID",this.jSessionId);
	builder.setHeader("Content-Type",MIME_FORM_ENCODING); 
	builder.setCallback(new RequestCallback()
	  	{
		public void onError(Request request, Throwable exception) {
				Window.alert("An error occured");
				}
	
		public void onResponseReceived(Request request, Response response) {
				Window.alert(response.getText());
				
			}
		  
	  	});
	try {
		builder.send();
	
		} catch (RequestException e) {
			Window.alert("Error  is: "+e.getMessage());
		}
	}
 
 private void doLogout()
 	{
	this.jSessionId=null;
	this.userIsAdmin=false;
	this.userIsAnonymous=true;
	if(pingRunner!=null)
		{
		try{pingRunner.cancel();} catch(Exception err) {}
		pingRunner=null;
		}
	buildWelcomeScreen();
 	}
  
  
 /** do Login */
 public void doLogin(TextBox login,PasswordTextBox password)
 	{
	String l= login.getText().trim();
	String pwd = password.getText().trim(); 
	if(l.length()==0) return;

	RequestBuilder builder = new RequestBuilder(RequestBuilder.POST,
			getGWTServlet()+"/login");
	builder.setHeader("Content-Type",MIME_FORM_ENCODING); 
	builder.setRequestData(
		"login="+URL.encode(l)+
		"&password="+URL.encode(pwd)
		);
	builder.setCallback(new RequestCallback()
	  	{
		public void onError(Request request, Throwable exception)
				{
				GWT.log("Error", exception);
				alert("An error occured");
				}
	
		public void onResponseReceived(Request request, Response response)
				{
				JSONObject object = null;
				try {
					object = parse(response);
					}catch(Exception err )
					{
					GWT.log("Error", err);
					alert("Login failed");
					return;
					}
				
				
				OperonGWTClient.this.jSessionId = object.get("JSESSIONID").isString().stringValue();
				if(jSessionId!=null)
					{
					OperonGWTClient.this.userLogin = object.get("login").isString().stringValue();
					OperonGWTClient.this.userIsAdmin = object.get("admin").isBoolean().booleanValue();
					OperonGWTClient.this.userIsAnonymous = object.get("anonymous").isBoolean().booleanValue();
					
					if(pingRunner!=null)
						{
						try{pingRunner.cancel();} catch(Exception err) {}
						pingRunner=null;
						}
					pingRunner= new PingRunner();
					pingRunner.scheduleRepeating(15*1000);
					
					buildGUI();
					doShowMainHelp();
					}
				else
					{
					alert("Cannot get JSESSSIONID");
					}
				
				}
		  
	  	});
	
	//builder.setHeader("Content-Type", "application/x-www-form-urlencoded"); 
	
	try {
		builder.send();
	
		} catch (RequestException e) {
			alert("Error  is: "+e.getMessage());
		}
 	}
  
 
 private void alert(String message)
 	{
	// Create the dialog box
	    final DialogBox dialogBox = new DialogBox();
	    dialogBox.setText(message);
	    dialogBox.setAnimationEnabled(true);
	    Button closeButton = new Button("close");
	    VerticalPanel dialogVPanel = new VerticalPanel();
	    dialogVPanel.setWidth("100%");
	    dialogVPanel.setHorizontalAlignment(VerticalPanel.ALIGN_CENTER);
	    dialogVPanel.add(closeButton);

	    closeButton.addClickListener(new ClickListener() {
	      public void onClick(Widget sender) {
	        dialogBox.hide();
	      }
	    });

	    // Set the contents of the Widget
	    dialogBox.setWidget(dialogVPanel);
	    
	    
	     dialogBox.center();
	     dialogBox.show();
	     
 	}
 
 /** show the projects visible by the current  user */
 private void showProjects()
 	{
	if(mainPanel==null) return;
	removeAll(this.mainPanel);
	try {
		RequestBuilder builder = new RequestBuilder(
				RequestBuilder.POST,
				getGWTServlet()+"/projects");
		Cookies.setCookie("JSESSIONID",this.jSessionId);
		builder.sendRequest(null,new ObjectCallBack(this.mainPanel)
	  		{
			@Override
			public void handleResponse(Request req, Response res) throws Exception
				{
				JSONObject o= parse(res);
				JSONArray array = o.get("message").isObject().get("table").isArray();
				Table grid= new Table(array.size(),4);
				
				grid.setColumnNames("ID","Definition","Author","Date");

				for(int i=0;i<array.size();++i)
					{
					JSONObject proj = array.get(i).isObject();
					
					String pid=proj.get("pid").isString().stringValue();
					Hyperlink h= new Hyperlink(pid,"project_"+pid);
					h.addClickListener(new ProjectClicked(pid));
					grid.setValueAt(i, 0,h);
					grid.setValueAt(i, 1, proj,"def");
					grid.setValueAt(i, 2, proj,"log");
					grid.setValueAt(i, 3, proj,"ymd");
					}
				DockPanel dock= new DockPanel();
				
				Frame frame01= new Frame("help/projects01.html");
				frame01.setStyleName("helpframe");
				dock.add(frame01,DockPanel.EAST);
				if(array.size()==0)
					{
					dock.add(new Label("No Projects was found."),DockPanel.CENTER);
					}
				else
					{
					dock.add(grid,DockPanel.CENTER);
					}
				DecoratorPanel dec= new DecoratorPanel();
				dec.setWidth("100%");
				dec.setWidget(dock);
				((Panel)getObject(0)).add(dec);
				}
	  		});
		} 
	catch (Exception e) {
		alert(e.getMessage());
		}
 	}

/** shows a panel specific for this given project */
 public void doShowProject(String pid)
 	{
	if(mainPanel==null) return;
	removeAll(this.mainPanel);
	
	try {
		RequestBuilder builder = new RequestBuilder(
				RequestBuilder.POST, 
				getGWTServlet()+"/project"
				);
		builder.setHeader("Content-Type",MIME_FORM_ENCODING); 
		Cookies.setCookie("JSESSIONID",this.jSessionId);
		
		try {
		builder.sendRequest("pid="+URL.encode(pid),new ObjectCallBack(this.mainPanel)
	  		{
			@Override
			public void handleResponse(Request req, Response res) throws Exception
				{
				
					DockPanel dock= new DockPanel();
					dock.setWidth("100%");
					JSONObject responseAsJSON= parse(res);
					JSONObject project = responseAsJSON.get("message").isObject().get("project").isObject();
					/* display project at top */
					Grid top= new Grid(4,2);
					top.setWidth("100%");
					dock.add(top,DockPanel.NORTH);
					
					String pid=project.get("pid").isString().stringValue();
					Label label= new Label("Project-ID");
					label.setStyleName("label4tableheader");
					top.setWidget(0,0,label);
					top.setWidget(0,1,new Label(pid));

					label= new Label("Definition");
					label.setStyleName("label4tableheader");
					top.setWidget(1,0,label);
					top.setWidget(1,1,new Label(project.get("def").isString().stringValue()));
					
					label= new Label("Author");
					label.setStyleName("label4tableheader");
					top.setWidget(2,0,label);
					top.setWidget(2,1,new Label(project.get("log").isString().stringValue()));
					
					label= new Label("Date");
					label.setStyleName("label4tableheader");
					top.setWidget(3,0,label);
					top.setWidget(3,1,new Label(project.get("ymd").isString().stringValue()));
					
					TabPanel tabPane= new TabPanel();
					tabPane.setWidth("100%");
					dock.add(tabPane,DockPanel.CENTER);
					
					//add prjdna,prjsnp,...
					for(String prjfin:new String[]{"prjdna","prjsnp"})
						{
						
						
						
						JSONArray jstable=responseAsJSON.isObject().get("message").isObject().get(prjfin).isArray();
						
						Table grid= new Table(jstable.size(),5);
						grid.setColumnNames("Fix","Definition","Author","Assembly","Date");
						
						
						for(int i=0;i<jstable.size();++i)
							{
							JSONObject prjx = jstable.get(i).isObject();
							
							
							String fix =prjx.get("fix").isString().stringValue();
							
							Anchor h= new Anchor(fix,
									getOperonBaseURL()+"/operon?act="+prjfin+"-edit&"+
									"pid="+URL.encode(pid)+"&fix="+URL.encode(fix)
									);
							h.setTarget(HIDDEN_FRAME_NAME);
							h.setTarget(pid+"_"+fix);
							
							grid.setValueAt(i, 0,h);
							grid.setValueAt(i, 1, prjx,"def");
							grid.setValueAt(i, 2,prjx,"log");
							grid.setValueAt(i, 3,toStr(prjx,"assembly.name"));
							grid.setValueAt(i, 4,prjx,"ymd");
							}
						tabPane.add(grid, prjfin);
						}
					
					/* add users */
					JSONArray jstable= path(responseAsJSON,"message.users").isArray();
					VerticalPanel pane0= new VerticalPanel();
					
					Table grid= new Table(jstable.size(),2);
					pane0.add(grid);
					
					grid.setColumnNames("ID","Name");
					List<CheckBox> userList= new ArrayList<CheckBox>();
					for(int i=0;i<jstable.size();++i)
						{
						JSONObject user = jstable.get(i).isObject();
						CheckBox cb=new CheckBox(toStr(user,"login"));
						userList.add(cb);
						grid.setValueAt(i, 0, cb);
						grid.setValueAt(i, 1, user,"login");
						}
					
					//change status of individuals for this project
					if(!userList.isEmpty())
						{
						HorizontalPanel h2= new HorizontalPanel();
						pane0.add(h2);
						ListBox actionBox= new ListBox(false);
						actionBox.setName("act");
						h2.add(actionBox);
						actionBox.addItem("-- --","");
						actionBox.addItem("Remove","prjmgr-remove-user");
						actionBox.addItem("Set As Administrator","prjmgr-user-admin");
						actionBox.addItem("Set As Writer","prjmgr-user-write");
						actionBox.addItem("Set As Read-only User","prjmgr-user-read");
						h2.add(new Button("Submit",new ClickAdapter(actionBox,userList,pid)
							{
							@SuppressWarnings("unchecked")
							@Override
							public void onClick(Widget w) {
								try {
									RequestBuilder builder = new RequestBuilder(
											RequestBuilder.POST,
											getGWTServlet()+"/adminprjmgr");
									Cookies.setCookie("JSESSIONID",jSessionId);
									
									StringBuffer sb= new StringBuffer();
									ListBox lb=(ListBox)getObject(0);
									List<CheckBox> userList=(List<CheckBox>)getObject(1);
									if(lb.getSelectedIndex()<1) return;
									if(userList.isEmpty()) return;
									sb.append("act=").append(URL.encode(lb.getValue(lb.getSelectedIndex())));
									
									Set<String> userIds= new HashSet<String>();
									for(CheckBox cb:userList)
										{
										if(!cb.isChecked()) continue;
										userIds.add(GWTUtils.getValue(cb));
										}
									if(userIds.isEmpty()) return;
									
									
									for(String s:userIds)
										{
										sb.append("&user-id=").append(URL.encode(s));
										}
									
									builder.sendRequest(sb.toString(),new ObjectCallBack(getObject(2))
								  		{
										@Override
										public void handleResponse(Request req, Response res) throws Exception
											{
											doShowProject((String)getObject(0));
											}
								  		});
									} 
								catch (Exception e) {
									alert(e.getMessage());
									}
								}
							}));
						}
					
					//add individuals for this project
					HorizontalPanel h2= new HorizontalPanel();
					h2.setWidth("100%");
					pane0.add(h2);
					label= new Label("Add User:");
					label.setStyleName("label4form");
					h2.add(label);
					TextBox userName=new TextBox();
					h2.add(userName);
					h2.add(new Button("Add User",new ClickAdapter(userName,pid)
						{
						@Override
						public void onClick(Widget w) {
							try {
								
								TextBox userName= (TextBox)getObject(0);
								if(userName.getText().trim().length()==0)
									{
									alert("Name is empty");
									return;
									}
							
							
								
								String pid= (String)getObject(1);
								
								RequestBuilder builder = new RequestBuilder(
										RequestBuilder.POST, 
										getGWTServlet()+"/prjmgradduser"
										);
								Cookies.setCookie("JSESSIONID",jSessionId);	
								builder.setHeader("Content-Type",MIME_FORM_ENCODING);
								
								StringBuffer sb= new StringBuffer("pid=");
								sb.append(URL.encode(pid));
								sb.append("&user-id=").append(URL.encode(userName.getText()));
								
								builder.sendRequest(sb.toString(),new ObjectCallBack(
										userName.getText(),pid)
							  		{
									@Override
									public void handleResponse(Request req, Response res) throws Exception
										{
										parse(res);//validate output
										doShowProject((String)getObject(1));
										alert("User "+getObject(0)+" was added to project");
										}
							  		});
								} 
							catch (Exception e) {
								alert("Error "+e.getMessage());
								}
							}
						}));
					tabPane.add(pane0, "Users");
					
					//Load SNP
					DockPanel dock01= new DockPanel();
					dock01.setWidth("100%");
					pane0= new VerticalPanel();
					pane0.setWidth("100%");
					dock01.add(pane0,DockPanel.CENTER);
					
					Frame frame01= new Frame("help/prj_load_snp.html");
					frame01.setStyleName("helpframe");
					dock01.add(frame01,DockPanel.EAST);
					
					FormPanel form= new FormPanel(hiddenFrame);
					form.setMethod(FormPanel.METHOD_POST);
					form.setEncoding(FormPanel.ENCODING_MULTIPART);
					form.setAction(getGWTServlet()+"/prjmgraddsnp");
					Hidden hidden= new Hidden("project-id",URL.encode(pid));
					pane0.add(hidden);
					form.setWidget(dock01);
					
					HorizontalPanel h3= new HorizontalPanel();
					JSONArray assemblies =path(responseAsJSON,"message.assemblies").isArray();
					ListBox lb= new ListBox();
					lb.setName("as");
					lb.addItem("-- --","");
					for(int i=0;i<assemblies.size();++i)
						{
						JSONObject org= assemblies.get(i).isObject();
						lb.addItem(toStr(org, "name"),toStr(org, "id"));
						}
					
					label= new Label("Assembly:");
					label.setStyleName("label4form");
					h3.add(label);
					h3.add(lb);
					pane0.add(h3);
					
					h3= new HorizontalPanel();
					TextBox snpListDef= new TextBox();
					snpListDef.setName("def");
					label= new Label("Definition:");
					label.setStyleName("label4form");
					h3.add(label);
					h3.add(snpListDef);
					pane0.add(h3);
					
					h3= new HorizontalPanel();
					label= new Label("File:");
					label.setStyleName("label4form");
					h3.add(label);
					FileUpload fileUpload= new FileUpload();
					fileUpload.setName("file");
					h3.add(fileUpload);
					pane0.add(h3);
					
					
					h3= new HorizontalPanel();
					label= new Label("Submit:");
					label.setStyleName("label4form");
					h3.add(label);
					h3.add(new Button("Submit",new ClickAdapter(form)
						{
						@Override
						public void onClick(Widget w) {
							((FormPanel)getObject(0)).submit();
							}
						}));
					pane0.add(h3);
					
					form.addFormHandler(new FormHandlerImpl(pid)
						{
						@Override
						public void onSubmit(FormSubmitEvent fse)
							{
							alert("List Submitted");
							doShowProject((String)getObject(0));
							}
						});
					
					tabPane.add(form, "Load SNP");
					
					
					
					tabPane.selectTab(0);
					DecoratorPanel dec= new DecoratorPanel();
					dec.setWidth("100%");
					dec.add(dock);
					((Panel)getObject(0)).add(dec);
					
				}
	  		});
		
			
			} catch (RequestException e) {
				alert("Error  is: "+e.getMessage());
			}
		} 
	catch (Exception e) {
		GWTUtils.log(e);
		GWTUtils.log("Error in show Project "+e.getMessage());
		}
 	}
	
 /** shows a panel specific for this given project */
 public void doShowExport()
 	{
	if(mainPanel==null) return;
	removeAll(this.mainPanel);
	ExportPane pane= new ExportPane();
	mainPanel.setWidget(pane.contentPane);
 	}
	
 /** shows a panel specific for this given project */
 public void doShowSNPMap()
 	{
	if(mainPanel==null) return;
	removeAll(this.mainPanel);
	SnpMapPane pane= new SnpMapPane();
	mainPanel.setWidget(pane.contentPane);
 	}
 
 
 public void doShowSpindleAlleles()
 	{
	 if(mainPanel==null) return;
	removeAll(this.mainPanel);
	SpindlePane pane= new SpindlePane();
	mainPanel.setWidget(pane.contentPane);
 	}
 
 private void doShowCreateUser()
 	{
	if(mainPanel==null) return;
	removeAll(this.mainPanel);
 	VerticalPanel pane= new VerticalPanel();
 	Grid grid= new Grid(4,2);
 	TextBox tbLogin= new TextBox();
 	PasswordTextBox tbPass1= new PasswordTextBox();
 	PasswordTextBox tbPass2= new PasswordTextBox();
 	CheckBox isAdmin= new CheckBox();
 	isAdmin.setChecked(false);
 	
 	grid.setWidget(0, 0, new Label("Login"));
 	grid.setWidget(0, 1, tbLogin);
 	grid.setWidget(1, 0, new Label("Password"));
 	grid.setWidget(1, 1, tbPass1);
 	grid.setWidget(2, 0, new Label("Re-Password"));
 	grid.setWidget(2, 1, tbPass2);
 	grid.setWidget(3, 0, new Label("Administrator"));
 	grid.setWidget(3, 1, isAdmin);
 	
 	pane.add(grid);
 	pane.add(new Button("Add",new ClickAdapter(tbLogin,tbPass1,tbPass2,isAdmin)
 		{
 		@Override
 		public void onClick(Widget w)
 			{
 			TextBox tLogin= (TextBox)getObject(0);
 			if(!tLogin.getText().matches("[a-zA-Z][a-zA-Z0-9]+"))
 				{
 				tLogin.setFocus(true);
 				alert("Bad login");
 				return;
 				}
 			
 			PasswordTextBox tbPass1= (PasswordTextBox)getObject(1);
 			PasswordTextBox tbPass2= (PasswordTextBox)getObject(2);
 			CheckBox isAdmin= (CheckBox)getObject(3);
 			
 			if(!tbPass1.getText().trim().equals(tbPass2.getText().trim()))
 				{
 				tbPass1.setFocus(true);
 				alert("Password doesn't match");
 				return;
 				}
 			if(tbPass1.getText().trim().length()==0)
 				{
 				alert("Password cannot be empty");
 				return;
 				}
 			
 			RequestBuilder builder = new RequestBuilder(
					RequestBuilder.POST,
					getGWTServlet()+"/createuser");
			Cookies.setCookie("JSESSIONID",jSessionId);
			builder.setHeader("Content-Type",MIME_FORM_ENCODING); 
			StringBuilder sb= new StringBuilder();
			sb.append("login=").append(URL.encode(tLogin.getText()))
				.append("&password=").append(URL.encode(tbPass1.getText().trim()))
				;
			if(isAdmin.isChecked())
				{
				sb.append("&admin=true");
				}
			
			try
				{
				builder.sendRequest(sb.toString(),new ObjectCallBack(tLogin.getText())
			  		{
					@Override
					public void handleResponse(Request req, Response res) throws Exception
						{
						buildGUI();
						alert("User "+getObject(0)+" was created");
						}
			  		});
				} 
			catch (Exception e) {
				alert(e.getMessage());
				}
 			}
 		
 		}));
 	DecoratorPanel dec= new DecoratorPanel();
 	dec.setTitle("Add a User");
 	dec.setWidget(pane);
 	mainPanel.add(pane);
 	}
 
 private void doShowMainHelp()
 	{
	 if(mainPanel==null) return;
	removeAll(this.mainPanel);
	DecoratorPanel dec= new DecoratorPanel();
	dec.setWidth("100%");
	DockPanel pane= new DockPanel();
	pane.setWidth("100%");
	Frame frame= new Frame("help/operon.html");
	frame.setWidth("100%");
	frame.setStyleName("helpframe");
	pane.add(frame,DockPanel.CENTER);
	dec.setWidget(pane);
	mainPanel.add(dec);
 	}
 
 private void doShowCreateProject()
	{
	if(mainPanel==null) return;
	removeAll(this.mainPanel);
	VerticalPanel pane= new VerticalPanel();
	pane.setWidth("100%");
	HorizontalPanel h= new HorizontalPanel();
	pane.add(h);
	TextBox name= new TextBox();
	h.add(new Label("Project Name:"));
	h.add(name);
	h= new HorizontalPanel();
	pane.add(h);
	TextBox def= new TextBox();
	h.add(new Label("Project Definition:"));
	h.add(def);
	
	pane.add(new Button("Add",new ClickAdapter(name,def)
		{
		@Override
		public void onClick(Widget w)
			{
			TextBox name= (TextBox)getObject(0);
			TextBox def= (TextBox)getObject(1);
			if(!name.getText().matches("[a-zA-Z][_a-zA-Z0-9]+"))
				{
				name.setFocus(true);
				alert("Bad Name");
				return;
				}
			if(def.getText().trim().length()==0)
				{
				def.setFocus(true);
				alert("Bad Definition");
				return;
				}
			String projName= name.getText().toUpperCase();
			RequestBuilder builder = new RequestBuilder(
					RequestBuilder.POST,
					getGWTServlet()+"/createproject");
			builder.setHeader("Content-Type",MIME_FORM_ENCODING); 
			Cookies.setCookie("JSESSIONID",jSessionId);
			StringBuilder sb= new StringBuilder();
			sb.append("pid=").append(URL.encode(projName))
				.append("&def=").append(URL.encode(def.getText().trim()))
				;
			
			try
				{
				builder.sendRequest(sb.toString(),new ObjectCallBack(projName)
			  		{
					@Override
					public void handleResponse(Request req, Response res) throws Exception
						{
						doShowProject((String)getObject(0));
						}
			  		});
				} 
			catch (Exception e) {
				GWTUtils.log(e);
				alert(e.getMessage());
				}
			GWTUtils.log("end creating proj");
			}
		
		}));
	DecoratorPanel dec= new DecoratorPanel();
	dec.setWidth("100%");
	dec.setWidget(pane);
	mainPanel.add(dec);
	}
 
/** parse a json as answer, check it is an object with status=200 */
private static JSONObject parse(Response response) 
	{
	JSONValue value=JSONParser.parse(response.getText());
	if(value==null)
		{
		throw new IllegalArgumentException("Bad Json. null");
		}
	JSONObject body= value.isObject();
	if(body==null)
		{
		throw new IllegalArgumentException("Bad Json. Not an object");
		}
	
	value=body.get("status");
	if(value==null)
		{
		throw new IllegalArgumentException("Bad Json. No Status");
		}
	JSONNumber num =value.isNumber();
	if(num==null) throw new IllegalArgumentException("Bad Json. Status is not a number");
	if(num.doubleValue()!=200.0)
		{
		value= body.get("message");
		if(value.isString()!=null)
			{
			throw new IllegalArgumentException("Error:"+value.isString().stringValue());
			}
		throw new IllegalArgumentException("Status!=200");
		}
	return body;
	}
 
private static JSONValue path(JSONValue o,String jspath)
	{
	if(o==null) return null;
	JSONObject obj = o.isObject();
	if(obj==null) return null;
	int i= jspath.indexOf(".");
	if(i!=-1)
		{
		JSONValue v= obj.get(jspath.substring(0,i));
		if(v==null) return null;
		return path(v,jspath.substring(i+1));
		}
	else
		{
		JSONValue v= obj.get(jspath);
		return v;
		}
	}

private static String toStr(JSONValue o,String jspath)
	{
	JSONValue v=path(o,jspath);
	if(v==null) return "null";
	if(v.isString()!=null) return v.isString().stringValue();
	if(v.isNumber()!=null) return String.valueOf(v.isNumber().doubleValue());
	if(v.isBoolean()!=null) return String.valueOf(v.isBoolean().booleanValue());
	return String.valueOf(v);
	}



}
